package com.siki.www.clock.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.siki.salessystemcommon.entity.ClockInfo;
import com.siki.salessystemcommon.entity.ClockLog;
import com.siki.salessystemcommon.mapper.ClockInfoMapper;
import com.siki.salessystemcommon.mapper.ClockLogMapper;
import com.siki.www.clock.dto.PageLogDTO;
import com.siki.www.clock.service.ClockLogService;
import com.siki.www.clock.vo.ClockLogVO;
import com.siki.www.clock.vo.CountInfoVO;
import com.siki.www.clock.vo.CountMsgDetailVO;
import com.siki.www.clock.vo.CountMsgVO;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author Keyvonchen in 2021/6/22
 */
@Service
public class ClockLogServiceImpl implements ClockLogService {


    private final ClockLogMapper clockLogMapper;
    private final ClockInfoMapper clockInfoMapper;

    public ClockLogServiceImpl(ClockLogMapper clockLogMapper, ClockInfoMapper clockInfoMapper) {
        this.clockLogMapper = clockLogMapper;
        this.clockInfoMapper = clockInfoMapper;
    }

    @Override
    public ClockLogVO get(Long id) {
        return new ClockLogVO(getLogById(id));
    }

    @Override
    public Page<ClockLogVO> getPageLog(PageLogDTO dto) {
        QueryWrapper<ClockLog> eq = new QueryWrapper<>();

        Optional.ofNullable(dto.getCasId()).ifPresent(d ->
                eq.like("cas_id", d)
        );

        Optional.ofNullable(dto.getName()).ifPresent(d ->
                eq.like("name", d)
        );

        Optional.ofNullable(dto.getDate()).ifPresent(d ->
                eq.eq("clock_date", d)
        );

        Optional.ofNullable(dto.getInDongGuan()).ifPresent(d ->
                eq.eq("in_dong_guan", d));

        Optional.ofNullable(dto.getInstitute()).ifPresent(d ->
                eq.like("institute", d)
        );

        Optional.ofNullable(dto.getTemperatureStatus()).ifPresent(d ->
                eq.eq("temperature_status", d)
        );

        Optional.ofNullable(dto.getPhysicalCondition()).ifPresent(d ->
                eq.eq("physical_condition", d)
        );

        Optional.ofNullable(dto.getPeopleType()).ifPresent(d ->
                eq.eq("people_type", d)
        );

        int page = Optional.ofNullable(dto.getPage()).orElse(0);
        int pageSize = Optional.ofNullable(dto.getPageSize()).orElse(10);

        return new Page<ClockLogVO>(page,
                pageSize, clockLogMapper.selectCount(eq))
                .setRecords(clockLogMapper.selectPage(new Page<>(page,
                                pageSize),
                        eq).getRecords()
                        .stream()
                        .map(ClockLogVO::new)
                        .collect(Collectors.toList()));
    }

    @Override
    public CountInfoVO count(String date) {
        CountInfoVO vo = new CountInfoVO();
        QueryWrapper<ClockLog> qw = new QueryWrapper<>();
        // 当天打卡人数
        qw.eq("clock_date", date);
        Integer clockCount = clockLogMapper.selectCount(qw);
        vo.setClockCount(clockCount);
        // 当天异常人数
        qw.eq("alert_status", 1);
        vo.setErrorCount(clockLogMapper.selectCount(qw));
        // 总人数
        Integer userCount = clockInfoMapper.selectCount(null);
        vo.setUserCount(userCount);
        // 未打卡人数 = 总人数 - 当天打卡人数
        vo.setUnClockCount(userCount - clockCount);
        return vo;
    }

    @Override
    public CountMsgVO count() {
        // 现在的 年月日
        LocalDate now = LocalDate.now();
        // 二十天前
        String reduce = now.minusDays(20L).format(DateTimeFormatter.ISO_LOCAL_DATE);
        QueryWrapper<ClockInfo> qw = new QueryWrapper<>();
        // 近20天打卡所有数据, [reduce, now]
        String format = now.format(DateTimeFormatter.ISO_LOCAL_DATE);
        List<Map<String, Object>> logs = clockLogMapper.getCountByTwentyDays(reduce, format);
        int userCount = clockInfoMapper.selectCount(qw.between("clock_date",
                reduce, format));
        CountMsgVO vo = new CountMsgVO();
        vo.setUserCount(userCount);
        vo.setDetail(logs.stream().map(CountMsgDetailVO::new)
                .peek(c -> c.setUnClockCount(userCount - c.getClockCount())).collect(Collectors.toList()));
        return vo;

    }

    /**
     * 查询日志
     */
    private ClockLog getLogById(Long id) {
        return Optional.ofNullable(clockLogMapper.selectById(id))
                .orElseThrow(() -> new RuntimeException("该id:" + id + "没有记录"));
    }
}
